#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Ethernet.h>
#include <ESP8266httpUpdate.h>
#include <ESP8266WebServer.h>
#include "ioUDP.h"
#include "ioOTA.h"
#include "ioMQTT.h"
#include "ioSerial.h"
#include "ioMsgHandler.h"
#include "ioUserSettings.h"
#include "ESP8266HTTPClient.h"
#include "ioIR.h"
#include "ioWebserver.h"
#include "iodevice.h"
#include "HLW9032.h"
struct uart_par_str
{
    unsigned char res_index;
    unsigned char res_buf[32]; //兼容bootloader，接收缓冲区设大点
};

struct HLW8032_STR HLW8032_data;
struct uart_par_str uart_par;

uint powerlist[20];
uint powerindex=0;

uint findmin(uint *list, uint length)
{
    uint i = 0;
    uint v = list[0];
    for (i = 1; i < length; i++)
    {
        if (v > list[i])
            v = list[i];
    }
    return v;
}

void hlw_loop()
{
    uint8_t i;
    uint32_t buffer;
    static uint32_t pubtime = 0;
    static uint32_t uart_timer = millis();

    if (Serial.available())
    {
        uart_timer = millis();
        uart_par.res_buf[uart_par.res_index] = Serial.read();
        uart_par.res_index++;
        uart_par.res_index &= 0x1f;
    }

    if (uart_par.res_index)
    {
        if (millis() - uart_timer > 10) //100ms时钟控制
        {
            if (HLW8032_data.pubnum > 0)
            {
                pubtime++;
                if (pubtime > 20 * 3)
                {
                    pubtime = 0;
                    HLW8032_data.pubnum--;
                    mqttPublishnum("$dp", "power", HLW8032_data.power_value);
                }
            }
            else if (HLW8032_data.power_value > 200)
            {
                pubtime++;
                if (pubtime > 20 * 30)
                {
                    pubtime = 0;
                    mqttPublishnum("$dp", "power", HLW8032_data.power_value);
                }
            }
            
            if (HLW8032_data.broadpower)
            {
                sendUDP_buffer(uart_par.res_buf, uart_par.res_index);
            }

            HLW8032_data.state = uart_par.res_buf[0];
            HLW8032_data.check = uart_par.res_buf[1];

            HLW8032_data.crc = 0;
            for (i = 2; i < 23; i++)
            {
                HLW8032_data.crc += uart_par.res_buf[i];
            }
            if (HLW8032_data.crc == uart_par.res_buf[23])
            {
                HLW8032_data.volt_par = (uart_par.res_buf[2] << 16) + (uart_par.res_buf[3] << 8) + (uart_par.res_buf[4] << 0);
                HLW8032_data.volt_value = (uart_par.res_buf[5] << 16) + (uart_par.res_buf[6] << 8) + (uart_par.res_buf[7] << 0);
                if (HLW8032_data.volt_value != 0)
                {
                    HLW8032_data.volt_value = HLW8032_data.volt_par * 188 / 10 / HLW8032_data.volt_value;
                }
                HLW8032_data.curr_par = (uart_par.res_buf[8] << 16) + (uart_par.res_buf[9] << 8) + (uart_par.res_buf[10] << 0);
                buffer = (uart_par.res_buf[11] << 16) + (uart_par.res_buf[12] << 8) + (uart_par.res_buf[13] << 0);

                if (buffer != 0)
                {
                    HLW8032_data.curr_value = (HLW8032_data.curr_value * 3 + (HLW8032_data.curr_par * 1000 / 5 / buffer)) / 4;
                    if (HLW8032_data.curr_value == 0)
                    {
                        HLW8032_data.curr_value = (HLW8032_data.curr_par * 1000 / 5 / buffer);
                    }
                }

                HLW8032_data.power_par = (uart_par.res_buf[14] << 16) + (uart_par.res_buf[15] << 8) + (uart_par.res_buf[16] << 0);
                buffer = (uart_par.res_buf[17] << 16) + (uart_par.res_buf[18] << 8) + (uart_par.res_buf[19] << 0);

                if (buffer)
                {
                    powerlist[powerindex] = HLW8032_data.power_par * 188 / 5 / buffer;
                    powerindex++;
                    if (powerindex >= 20)
                        powerindex = 0;
                }

                HLW8032_data.power_value = findmin(powerlist,20);

                HLW8032_data.pf = (uart_par.res_buf[21] << 16) + (uart_par.res_buf[18] << 8) + (uart_par.res_buf[22] << 0);
            }
            uart_par.res_index = 0;
        }
    }
}